package com.gcit.seniorWish.web.modular.enroll.service.impl;

import java.io.InputStream;
import java.lang.reflect.Field;
import java.util.*;

import javax.annotation.Resource;

import cn.hutool.core.util.ReUtil;
import com.gcit.seniorWish.web.common.constant.cache.Cache;
import com.gcit.seniorWish.web.common.constant.cache.CacheKey;
import com.gcit.seniorWish.web.common.persistence.dao.*;
import com.gcit.seniorWish.web.common.persistence.model.*;
import com.gcit.seniorWish.web.modular.enroll.dao.EnrollSchoolBatchMajorDao;
import com.gcit.seniorWish.web.modular.examinee.dao.SeniorWishDao;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.baomidou.mybatisplus.mapper.Condition;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.plugins.Page;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.gcit.seniorWish.core.exception.GunsException;
import com.gcit.seniorWish.core.node.SelectNode;
import com.gcit.seniorWish.web.common.constant.factory.ConstantFactory;
import com.gcit.seniorWish.web.core.exception.BizExceptionEnum;
import com.gcit.seniorWish.web.modular.enroll.dao.EnrollSchoolDao;
import com.gcit.seniorWish.web.modular.enroll.service.IEnrollSchoolService;
import com.gcit.seniorWish.web.modular.enroll.transfer.EnrollSchoolDto;
import com.gcit.seniorWish.web.modular.enroll.transfer.EnrollSchoolMajorDto;

import cn.hutool.core.util.StrUtil;
import cn.hutool.poi.excel.ExcelReader;
import cn.hutool.poi.excel.ExcelUtil;

/**
 * <p>
 * 报考学校信息表（提前录取（师范）、提前批次（普高）、指标生录取、第一批次、第二批次、第三批次、第四批次、第五批次） 服务实现类
 * </p>
 *
 * @author gaozhichang
 * @since 2018-03-16
 */
@Service
public class EnrollSchoolServiceImpl extends ServiceImpl<EnrollSchoolMapper, EnrollSchool>
		implements IEnrollSchoolService {

	@Resource
	private SchoolBatchRelationMapper schoolBatchRelationMapper;

	@Resource
	private EnrollSchoolDao enrollSchoolDao;

	@Resource
	private EnrollSchoolMapper enrollSchoolMapper;

	@Resource
	private DictMapper dictMapper;

	@Resource
	private EnrollSchoolBatchMajorMapper enrollSchoolBatchMajorMapper;

	@Resource
	private EnrollSchoolBatchMajorDao enrollSchoolBatchMajorDao;


	@Resource
	private SeniorWishDao seniorWishDao;

	/**
	 * 查询报考学校列表
	 *
	 * @param
	 * @author gaozhichang
	 * @date 2018-04-04 上午 9:43
	 */
	@Override
	public List<EnrollSchool> listEnrollSchool(Page page, EntityWrapper<EnrollSchool> ew) {
		List<EnrollSchool> enrollSchoolList = enrollSchoolDao.listEnrollSchoolWithBatchType(page, ew);

		return enrollSchoolList;
	}

	/**
	 * 新增报考学校
	 *
	 * @param enrollSchool 新增的报考学校
	 * @author gaozhichang
	 * @date 2018-03-19 上午 9:43
	 */
	@Override
	@Transactional
	public void addEnrollSchool(EnrollSchool enrollSchool) {
		// 判断学校代号是否存在
		if (baseMapper.selectCount(Condition.create().eq("school_code", enrollSchool.getSchoolCode())) > 0) {
			throw new GunsException(BizExceptionEnum.ENROLL_SCHOOL_CODE_EXISTED);
		}
		baseMapper.insert(enrollSchool);
		// 判断学校报考批次是否存在
		if (StrUtil.isNotBlank(enrollSchool.getBatchTypes())) {
			for (String batchType : enrollSchool.getBatchTypes().split(",")) {
				SchoolBatchRelation relation = new SchoolBatchRelation();
				relation.setSchoolId(enrollSchool.getId());
				relation.setSeniorWishBatchType(Integer.parseInt(batchType));
				schoolBatchRelationMapper.insert(relation);
			}
		}
	}

	/**
	 * 修改报考学校
	 *
	 * @param enrollSchool 修改的报考学校
	 * @author gaozhichang
	 * @date 2018-03-19 上午 9:43
	 */
	@Override
	@Transactional
	@CacheEvict(value = Cache.BUSS, key = "'" + CacheKey.ENROLL_SCHOOL + "'+#enrollSchool.id")
	public void updateEnrollSchool(EnrollSchool enrollSchool) {
		// 判断学校代号是否存在
		EntityWrapper<EnrollSchool> ew = new EntityWrapper();
		if (baseMapper.selectCount(Condition.create().ne("id", enrollSchool.getId()).eq("school_code",
				enrollSchool.getSchoolCode())) > 0) {
			throw new GunsException(BizExceptionEnum.ENROLL_SCHOOL_CODE_EXISTED);
		}

		baseMapper.updateById(enrollSchool);
		// 删除当前已经配置的学校报考批次
		schoolBatchRelationMapper.delete(Condition.create().eq("school_id", enrollSchool.getId()));
		// 判断学校报考批次是否存在
		if (StrUtil.isNotBlank(enrollSchool.getBatchTypes())) {
			for (String batchType : enrollSchool.getBatchTypes().split(",")) {
				SchoolBatchRelation relation = new SchoolBatchRelation();
				relation.setSchoolId(enrollSchool.getId());
				relation.setSeniorWishBatchType(Integer.parseInt(batchType));
				schoolBatchRelationMapper.insert(relation);
			}
		}
	}

	/**
	 * 查询报考志愿类型列表
	 *
	 * @param enrollSchoolId 报考学校id，若存在，只查询该学校报考的学校id
	 * @author gaozhichang
	 * @date 2018-03-19 下午 3:22
	 */
	@Override
	public List<SelectNode> listBatchTypeForSelect2(String enrollSchoolId) {
		List<Dict> typeList = ConstantFactory.me().listDictsByPCode("senior_wish_batch_type");
		List<SelectNode> selectList = new ArrayList<>();
		List<Integer> batchTypeList = null;
		if (StrUtil.isNotBlank(enrollSchoolId)) {
			batchTypeList = enrollSchoolDao.listEnrollSchoolBatchType(enrollSchoolId);
		}
		for (Dict dict : typeList) {
			// 数组为空，或者数组中存在当前类型，返回该报考类型
			if (batchTypeList == null || batchTypeList.contains(Integer.parseInt(dict.getValue()))) {
				SelectNode node = new SelectNode();
				node.setId(dict.getValue());
				node.setText(dict.getName());
				selectList.add(node);
			}
		}
		return selectList;
	}

	/**
	 * 查询报考学校列表
	 *
	 * @param batchType      按批次类型查询报考学校
	 * @param enrollSchoolId 查询指定的学校
	 * @author gaozhichang
	 * @date 2018-03-20 上午 11:25
	 */
	@Override
	public List<Map<String, Object>> listEnrollSchoolForSelect2(Page<Map<String, Object>> page, Integer batchType, String enrollSchoolId, String enrollSchoolName) {
		if (StrUtil.isNotBlank(enrollSchoolName)) {
			enrollSchoolName = "%" + enrollSchoolName + "%";
		}
		return enrollSchoolDao.listEnrollSchoolForSelect2(page, batchType, enrollSchoolId, enrollSchoolName);
	}

	/**
	 * 导入报考学校处理
	 */
	@SuppressWarnings({"rawtypes", "unchecked"})
	@Override
	@Transactional
	public String importEnrollSchool(InputStream inputStream) {
		StringBuffer msg = new StringBuffer();
		ExcelReader reader = ExcelUtil.getReader(inputStream);
		Map<String, String> headerAlias = new HashMap<String, String>();
		headerAlias.put("报考学校编号", "enrollSchoolCode");
		headerAlias.put("报考学校名称", "enrollSchoolName");
		headerAlias.put("报考专业编号", "majorCode");
		headerAlias.put("报考专业名称", "majorName");
		headerAlias.put("专业学制", "schoolLength");
		headerAlias.put("参与志愿批次", "DictName");
		reader.setHeaderAlias(headerAlias);
		List<EnrollSchoolDto> excelData = reader.readAll(EnrollSchoolDto.class);
		if (excelData.size() > 0) {
			Iterator excelIt = excelData.iterator();
			EnrollSchoolDto item = null;
			int i = 0;
			//循环列表中的记录
			while (excelIt.hasNext()) {
				i++;
				item = (EnrollSchoolDto) excelIt.next();
				//判断必填内容是否填写 填写报考学校的时候 报考学校名称和报考学校编号 以及报考志愿批次一定填写
				if (StrUtil.isBlank(item.getEnrollSchoolName())) {
					msg.append("第" + i + "条缺少报考学校名称\n");
					continue;
				}
				if (StrUtil.isBlank(item.getEnrollSchoolCode())) {
					msg.append("第" + i + "条缺少报考学校编号\n");
					continue;
				}
				if (StrUtil.isBlank(item.getDictName())) {
					msg.append("第" + i + "条缺少参与志愿批次\n");
					continue;
				}
				//当专业编号存在时，判断专业信息是否正确
				if (StrUtil.isNotBlank(item.getMajorCode())) {
					if (StrUtil.isBlank(item.getMajorName())) {
						msg.append("第" + i + "条缺少报考专业名称\n");
						continue;
					}
					if (enrollSchoolBatchMajorDao.getEnrollMajorCountBySchoolCodeAndMajorCode(item.getEnrollSchoolCode(),item.getMajorCode())> 0) {
						msg.append("第" + i + "条报考专业编号在"+item.getEnrollSchoolName()+"中已存在\n");
						continue;
					}
				}
			}
			//当导入数据判断没有问题时，开始导入数据
			if (StrUtil.isBlank(msg.toString())) {
				//由于专业与学校一起导入，所以导入数据中会存在多个重复的学校信息
				//建立已处理的学校map(key为学校代码_参与的批次,value为报考学校id)减少数据库判断学校存在的次数
				Map<String, String> processedSchoolIdMap = new HashMap<>();
				for (EnrollSchoolDto es : excelData) {
					//判断该学校该批次是否已经处理过
					if (!processedSchoolIdMap.containsKey(es.getEnrollSchoolCode()+"_"+es.getDictName())) {
						EnrollSchool enrollSchool = null;
						//查询当前添加的学校是否已存在
						if (enrollSchoolMapper.selectCount(Condition.create().eq("school_code", es.getEnrollSchoolCode())) > 0) {
							List<EnrollSchool> list = enrollSchoolMapper.selectList(Condition.create().eq("school_code", es.getEnrollSchoolCode()));
							if (list != null && list.size() == 1) {
								enrollSchool = list.get(0);
							}
						} else {//新增学校
							enrollSchool = new EnrollSchool();
							enrollSchool.setSchoolCode(es.getEnrollSchoolCode());
							enrollSchool.setSchoolName(es.getEnrollSchoolName());
							baseMapper.insert(enrollSchool);
						}
						// 通过批次名查询批次代码
						List<Dict> dictList = dictMapper.selectList(Condition.create().eq("pcode","senior_wish_batch_type").eq("name", es.getDictName()));
						if (dictList.size() <= 0) {
							throw new GunsException(400, es.getDictName() + "批次不存在！");
						}
						Dict batchDict = dictList.get(0);
						// 判断当前学校当前批次是否存在,不存在。新增关系
						if (schoolBatchRelationMapper.selectCount(Condition.create().eq("school_id", enrollSchool.getId())
								.eq("senior_wish_batch_type", Integer.parseInt(batchDict.getValue()))) <= 0) {
							SchoolBatchRelation schoolBatchRelation = new SchoolBatchRelation();
							schoolBatchRelation.setSchoolId(enrollSchool.getId());
							schoolBatchRelation.setSeniorWishBatchType(Integer.parseInt(batchDict.getValue()));
							schoolBatchRelationMapper.insert(schoolBatchRelation);
						}
						//将处理过的学校新增到map中，方便新增专业时获取
						processedSchoolIdMap.put(es.getEnrollSchoolCode()+"_"+es.getDictName(), enrollSchool.getId());
					}
					//当专业代码不存在时，新增专业
					if(StrUtil.isNotBlank(es.getMajorCode())){
						// 通过批次名查询批次代码  当学校代码和志愿名称 存在是 只是导入专业名称
					List<Dict> dictList1 = dictMapper.selectList(Condition.create().eq("pcode","senior_wish_batch_type").eq("name", es.getDictName()));
						if (dictList1.size() <= 0) {
							throw new GunsException(400, es.getDictName() + "批次不存在！");
						}
						Dict batchDict1 = dictList1.get(0);
						EnrollSchoolBatchMajor enrollSchoolBatchMajor = new EnrollSchoolBatchMajor();
						enrollSchoolBatchMajor.setEnrollSchoolId(processedSchoolIdMap.get(es.getEnrollSchoolCode()+"_"+es.getDictName()));
						enrollSchoolBatchMajor.setMajorCode(es.getMajorCode());
						enrollSchoolBatchMajor.setMajorName(es.getMajorName());
						enrollSchoolBatchMajor.setBatchType(Integer.parseInt(batchDict1.getValue()));
						enrollSchoolBatchMajor.setSchoolLength(es.getSchoolLength());
						enrollSchoolBatchMajorMapper.insert(enrollSchoolBatchMajor);
					}
				}
			}
		} else {
			msg.append("导入模板为空\n");
		}
		return msg.toString();

	}

	/**
	 * 导入报考专业信息处理
	 * @deprecated  导入专业合并到导入学校中
	 */
	@SuppressWarnings({"rawtypes", "unchecked"})
	@Override
	@Transactional
	public String importMajor(InputStream inputStream) {

		Map<String, List<String>> majormap = new HashMap<>();
		List<EnrollSchool> list = new ArrayList<>();
		List<EnrollSchoolBatchMajor> majors = new ArrayList<>();
		StringBuffer msg = new StringBuffer();
		ExcelReader reader = ExcelUtil.getReader(inputStream);
		Map<String, String> headerAlias = new HashMap<String, String>();
		headerAlias.put("报考学校编号", "EnrollSchoolCode");
		headerAlias.put("报考学校名称", "EnrollSchoolName");
		headerAlias.put("报考专业编号", "MajorCode");
		headerAlias.put("报考专业名称", "MajorName");
		reader.setHeaderAlias(headerAlias);
		List<EnrollSchoolMajorDto> excelData = reader.readAll(EnrollSchoolMajorDto.class);
		if (excelData.size() > 0) {
			Iterator excelIt = excelData.iterator();
			EnrollSchoolMajorDto item = null;
			int i = 0;
			// 循环列表中的记录
			while (excelIt.hasNext()) {
				i++;
				item = (EnrollSchoolMajorDto) excelIt.next();
				//判断必填内容是否填写
				if (StrUtil.isBlank(item.getMajorName())) {
					msg.append("第" + i + "条缺少报考专业名称\n");
					continue;
				}
				if (StrUtil.isBlank(item.getEnrollSchoolCode())) {
					msg.append("第" + i + "条缺少报考学校编号\n");
					continue;

				} else {
					//根据学校编号查询学校信息
					list = baseMapper.selectList(Condition.create().eq("school_code", item.getEnrollSchoolCode()));
					if (list.size() == 0) {
						msg.append("第" + i + "条报考学校编号不存在，请先行添加报考学校信息\n");
						continue;
					}
				}
				if (StrUtil.isBlank(item.getMajorCode())) {
					msg.append("第" + i + "条缺少专业代码\n");
					continue;
				} else {

					//Set<String> strings = majormap.keySet();
					//for (String key:strings){
					//	if(!key.equals(item.getEnrollSchoolCode())){
					//		majorList = new ArrayList<>() ;
					//	}
					//}
					List<String> majorcode = majormap.get(item.getEnrollSchoolCode());
					if (majorcode == null) {
						List<String> majorList = new ArrayList<>();
						majorList.add(item.getMajorCode());
						majormap.put(item.getEnrollSchoolCode(), majorList);
						list = baseMapper.selectList(Condition.create().eq("school_code", item.getEnrollSchoolCode()));
						if (list != null && list.size() == 1) {
							EnrollSchool enrollSchool = list.get(0);
							//根据学校信息查询专业信息
							majors = enrollSchoolBatchMajorMapper.selectList(Condition.create().eq("enroll_school_id", enrollSchool.getId()).eq("del_flag", 0));
							for (EnrollSchoolBatchMajor major : majors) {
								if (major.getMajorCode().equals(item.getMajorCode())) {
									msg.append("第" + i + "条报考专业编号已存在\n");
									continue;
								}
							}

						} else {
							msg.append("第" + i + "条报考学校编号不存在，请先行添加报考学校信息\n");
							continue;
						}
					} else if (!majorcode.contains(item.getMajorCode())) {
						majorcode.add(item.getMajorCode());
						majormap.put(item.getEnrollSchoolCode(), majorcode);
						list = baseMapper.selectList(Condition.create().eq("school_code", item.getEnrollSchoolCode()));
						if (list != null && list.size() == 1) {
							EnrollSchool enrollSchool = list.get(0);
							//根据学校信息查询专业信息
							majors = enrollSchoolBatchMajorMapper.selectList(Condition.create().eq("enroll_school_id", enrollSchool.getId()).eq("del_flag", 0));
							for (EnrollSchoolBatchMajor major : majors) {
								if (major.getMajorCode().equals(item.getMajorCode())) {
									msg.append("第" + i + "条报考专业编号已存在\n");
									continue;
								}
							}

						} else {
							msg.append("第" + i + "条报考学校编号不存在，请先行添加报考学校信息\n");
							continue;
						}
					} else if (majorcode.contains(item.getMajorCode())) {
						msg.append("第" + (i + 1) + "条专业编号重复\n");
						continue;
					}
				}
			}
			if (StrUtil.isBlank(msg.toString())) {
				//数据保存
				for (EnrollSchoolMajorDto major : excelData) {
					EnrollSchoolBatchMajor inputMajor = new EnrollSchoolBatchMajor();
					List<EnrollSchool> list1 = baseMapper.selectList(Condition.create().eq("school_code", major.getEnrollSchoolCode()));
					if (list1 != null && list1.size() == 1) {
						EnrollSchool school = list1.get(0);
						inputMajor.setEnrollSchoolId(school.getId());
						inputMajor.setMajorCode(major.getMajorCode());
						inputMajor.setMajorName(major.getMajorName());
						enrollSchoolBatchMajorMapper.insert(inputMajor);
					}

				}
			} else {
				msg.append("请修正数据后重新导入！\n");
			}
		}
		return msg.toString();
	}

	/**
	 * 删除报考学校
	 *
	 * @param enrollSchoolId 报考学校id
	 * @author gaozhichang
	 * @date 2018-03-30 下午 3:08
	 */
	@Override
	@Transactional
	@CacheEvict(value = Cache.BUSS, key = "'" + CacheKey.ENROLL_SCHOOL + "'+#enrollSchoolId")
	public void deleteEnrollSchool(String enrollSchoolId) {
		List<String> schoolIdFieldList = new ArrayList<>();
		Field[] fields = SeniorWish.class.getDeclaredFields();
		for (int i = 0; i < fields.length; i++) {
			Field field = fields[i];
			//设置可以访问私有变量
			field.setAccessible(true);
			if (ReUtil.findAll("School\\dId", field.getName(), 0).size() > 0) {
				schoolIdFieldList.add(StrUtil.toUnderlineCase(field.getName()));
			}
		}
		if (seniorWishDao.selectSchoolCheckedCount(schoolIdFieldList, enrollSchoolId) > 0) {
			throw new GunsException(BizExceptionEnum.ENROLL_SCHOOL_ENROLLED);
		}
		baseMapper.deleteById(enrollSchoolId);
		//删除学校之后 该学校的专业也删除
		enrollSchoolBatchMajorMapper.delete(Condition.create().eq("enroll_school_id" ,enrollSchoolId)) ;
	}
}
